﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.AccessControl;
using System.IO;
using System.Management;

namespace backfile.util
{
    public class ShareFolder
    {
        private static readonly Dictionary<uint, string> ReturnDetails = new Dictionary<uint, string>();

        /// <summary>
        /// Success (0)
        /// Access denied (2)
        /// Unknown failure (8)
        /// Invalid name (9)
        /// Invalid level (10)
        /// Invalid parameter (21)
        /// Duplicate share (22)
        /// Redirected path (23)
        /// Unknown device or directory (24)
        /// Net name not found (25)
        /// Other (26–4294967295)
        /// </summary>
        static ShareFolder()
        {
            ReturnDetails.Add(0, "Success");
            ReturnDetails.Add(2, "Access denied");
            ReturnDetails.Add(8, "Unknown failure");
            ReturnDetails.Add(9, "Invalid name");
            ReturnDetails.Add(10, "Invalid level");
            ReturnDetails.Add(21, "Invalid parameter");
            ReturnDetails.Add(22, "Duplicate share");
            ReturnDetails.Add(23, "Redirected path");
            ReturnDetails.Add(24, "Unknown device or directory");
            ReturnDetails.Add(25, "Net name not found");
        }

        /// <summary>
        /// 设置文件夹共享  
        /// </summary>  
        /// <param name="folderPath">文件夹路径</param>  
        /// <param name="shareName">共享名</param>  
        /// <param name="description">共享注释</param>
        /// <returns></returns> 
        public static void Share(string folderPath, string shareName, string description)
        {
            var directoryInfo = new DirectoryInfo(folderPath);
            DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
            directorySecurity.AddAccessRule(new FileSystemAccessRule("everyone", FileSystemRights.FullControl,
                InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
            directoryInfo.SetAccessControl(directorySecurity);

            var managementClass = new ManagementClass("Win32_Share");
            // Create ManagementBaseObjects for in and out parameters  
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
            ManagementBaseObject outParams;
            // Set the input parameters  
            inParams["Description"] = description;
            inParams["Name"] = shareName;
            inParams["Path"] = folderPath;
            inParams["Type"] = 0; // Disk Drive  
            inParams["MaximumAllowed"] = null;
            inParams["Password"] = null;
            inParams["Access"] = null; // Make Everyone has full control access.
            outParams = managementClass.InvokeMethod("Create", inParams, null);
            // Check to see if the method invocation was successful  
            uint result = (uint)(outParams.Properties["ReturnValue"].Value);

            if (result != 0)
            {
                if (ReturnDetails.ContainsKey(result))
                {
                    throw new Exception(ReturnDetails[result]);
                }
                else
                {
                    throw new Exception("failed to create share folder");
                }
            }
        }
    }
}
